package io;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Scanner;

public class MMapVsTraditionalIO {

    private static final int NUM_LINES = 10_000_000;
    private static final String LINE_CONTENT = "This is a line of text.\n";
    private static final int LINE_LENGTH = LINE_CONTENT.length();

    public static void main(String[] args) throws IOException {

        // 获取用户目录
        String userDirectory = System.getProperty("user.home");
        // 获取文件分隔符
        String fileSeparator = System.getProperty("file.separator");
        String indexpath = userDirectory + fileSeparator + "Desktop" + fileSeparator;
        String mmapFilePath = indexpath + "mmap_output.txt";
        String traditionalFilePath = indexpath + "traditional_output.txt";

        // Measure time for mmap
        long mmapStartTime = System.currentTimeMillis();
        writeUsingMMap(mmapFilePath);
        long mmapEndTime = System.currentTimeMillis();
        long mmapDuration = mmapEndTime - mmapStartTime;

        // Measure time for traditional I/O
        long traditionalStartTime = System.currentTimeMillis();
        writeUsingTraditionalIO(traditionalFilePath);
        long traditionalEndTime = System.currentTimeMillis();
        long traditionalDuration = traditionalEndTime - traditionalStartTime;

        // Print results
        System.out.println("MMap write duration: " + mmapDuration + " ms");
        System.out.println("Traditional I/O write duration: " + traditionalDuration + " ms");

        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入一些文字：");
        String input = scanner.nextLine(); // 等待用户输入文本并按回车
        System.out.println("你输入了: " + input);

        scanner.close();
    }

    private static void writeUsingMMap(String filePath) throws IOException {
        try (RandomAccessFile file = new RandomAccessFile(filePath, "rw");
             FileChannel fileChannel = file.getChannel()) {

            long fileSize = (long) NUM_LINES * LINE_LENGTH;
            MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, fileSize);

            for (int i = 0; i < NUM_LINES; i++) {
                mappedByteBuffer.put(LINE_CONTENT.getBytes());
            }
        }
    }

    private static void writeUsingTraditionalIO(String filePath) throws IOException {
        try (FileWriter writer = new FileWriter(filePath)) {
            for (int i = 0; i < NUM_LINES; i++) {
                writer.write(LINE_CONTENT);
            }
        }
    }
}
